package io.kimmking.statemachine01;

import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;

import java.util.EnumSet;

@EnableStateMachine
@Configuration
public class StatemachineConfigurer extends EnumStateMachineConfigurerAdapter<TurnstileStates, TurnstileEvents> {

    @Override
    public void configure(StateMachineStateConfigurer<TurnstileStates, TurnstileEvents> states)
            throws Exception {
        states.withStates()    // 配置 初始状态和状态集合
                .initial(TurnstileStates.Locked)                  // 初始状态：Locked
                .states(EnumSet.allOf(TurnstileStates.class));    // 所有状态
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<TurnstileStates, TurnstileEvents> transitions)
            throws Exception {
        transitions.withExternal()    // 配置 事件=>状态转移+操作
                .source(TurnstileStates.Locked).target(TurnstileStates.Unlocked)
                .event(TurnstileEvents.COIN).action(turnstileUnlock())

                .and()
                .withExternal()
                .source(TurnstileStates.Unlocked).target(TurnstileStates.Locked)
                .event(TurnstileEvents.PUSH).action(customerPassAndLock());

//                .and()
//                .withExternal()
//                .source(TurnstileStates.Unlocked).target(TurnstileStates.Unlocked)
//                .event(TurnstileEvents.COIN).action( c -> System.out.println(" more coins is no use."))
//
//                .and()
//                .withExternal()
//                .source(TurnstileStates.Locked).target(TurnstileStates.Locked)
//                .event(TurnstileEvents.PUSH).action( c -> System.out.println(" push must be after coin."));


    }

    @Override
    public void configure(StateMachineConfigurationConfigurer<TurnstileStates, TurnstileEvents> config)
            throws Exception {
        config.withConfiguration().machineId("turnstileStateMachine");
    }

    public Action<TurnstileStates, TurnstileEvents> turnstileUnlock() {
        return context -> System.out.println("coin解锁旋转门，以便游客能够通过.");
    }

    public Action<TurnstileStates, TurnstileEvents> customerPassAndLock() {
        return context -> System.out.println("当游客push通过，锁定旋转门.");
    }

}
